package com.yuanian.timingwheel.model.task.base;

import com.alibaba.fastjson.JSONObject;
import com.yuanian.timingwheel.context.ExecutionContext;
import com.yuanian.timingwheel.respository.po.TaskEntity;

import java.io.Serializable;
import java.util.Date;

/**
 * 任务的信息，所有的任务归根结底都是在执行时间去执行，执行多少次，间隔多长时间
 */
public class TaskExecutionInfo implements Serializable {

    //间隔秒数
    protected long executionInterval;
    //执行次数
    protected long executionRounds;
    //下次执行时间
    protected Date executionTime;
    //已经执行次数
    protected long executedRounds;

    public TaskExecutionInfo(long executionInterval, long executionRounds, Date executionTime) {
        this(executionInterval, executionRounds, 0, executionTime);
    }

    public TaskExecutionInfo(long executionInterval, long executionRounds, long executedRounds, Date executionTime) {
        this.executionInterval = executionInterval;
        this.executionRounds = executionRounds;
        this.executionTime = executionTime;
        this.executedRounds = executedRounds;
    }

    /**
     * 是否还可以再次运行
     * @return
     */
    public boolean canExecute() {
        return this.executionRounds > 0 && this.executionRounds > this.executedRounds;
    }

    /**
     * 任务执行后置操作
     */
    public void postExecute(BaseTask task, Object result) {
        if (task.getId() != null) {//不是附加任务
            executedRounds++;
            if (canExecute()) {
                //从当前时间算，而不是从执行时间算
                executionTime.setTime(new Date().getTime() + executionInterval * 1000);
                //为了提高间隔执行的性能，在最后一次去更新
                //TaskEntity.update(task);
                //重新加入任务到时间轮
                ExecutionContext.getInstance().getDayTimingWheel().loadTask(task);
            } else {
                TaskExecutionResult taskExecutionResult = new TaskExecutionResult(true, "success");
                String resultStr = JSONObject.toJSONString(result);
                if (resultStr.length() > 8000) {
                    resultStr = resultStr.substring(0, 8000);
                }
                taskExecutionResult.setResult(resultStr);
                task.setTaskExecutionResult(taskExecutionResult);
                TaskEntity.update(task);
            }
        }
    }

    public long getExecutionInterval() {
        return executionInterval;
    }

    public void setExecutionInterval(long executionInterval) {
        this.executionInterval = executionInterval;
    }

    public long getExecutionRounds() {
        return executionRounds;
    }

    public void setExecutionRounds(long executionRounds) {
        this.executionRounds = executionRounds;
    }

    public Date getExecutionTime() {
        return executionTime;
    }

    public void setExecutionTime(Date executionTime) {
        this.executionTime = executionTime;
    }

    public long getExecutedRounds() {
        return executedRounds;
    }

}
